#ifndef __W25QXX_H__
#define __W25QXX_H__

#include "device.h"

#ifdef __cplusplus
extern "C" {
#endif

// W25QXX扇区大小
#define SECTOR_SIZE 4096  

// W25QXX页大小
#define PAGE_SIZE 256 
// W25QXX设备结构体
// UART结构体
DEVICE_FEATURE_DECLARE 
(
    W25QXX,
    struct {

        /**
         * @brief SPI发送接收函数指针
         * @param pu8TxBuffer 发送缓冲区
         * @param pu8RxBuffer 接收缓冲区
         * @param u32Len 发送/接收长度
         * @return 0:成功; 其他:失败
         * 
         * @note 该函数指针用于SPI发送/接收数据，根据实际情况修改
         */
        uint8_t
        (*pfnTransRecv)(uint8_t* pu8TxBuffer, uint8_t* pu8RxBuffer, uint32_t u32Len);
        
        /**
         * @brief 片选控制函数指针
         * @param u8Enable 片选使能/失能
         * @return 0:成功; 其他:失败
         */
        void
        (*pfnCS)(uint8_t u8Enable);
    },
    struct {
        uint8_t u8CSActive;     // 片选状态
        uint8_t* pu8SecCache;   // 扇区缓存 -- 用于写扇区数据时临时存储数据
        uint32_t u32RetryNum;   // 重试次数 -- 根据SPI速率调整
    }
);

/**
 * @brief W25QXX设备注册
 * @param pstSelf W25QXX设备结构体
 * @return Device_t* 注册成功返回设备结构体指针，失败返回NULL
 */
DEV_REG_DEC(w25qxx, W25QXX_t)

/**
 * @brief W25QXX设备读取设备ID
 * @param pstDevice W25QXX设备
 * @param pu16ID 设备ID指针
 * @return 发送成功返回DEV_RET_OK，否则返回错误码 @see DEV_RET_t
 *
 * @note 读取W25QXX设备ID，可用于测试W25QXX是否正常工作
 */
DEV_RET_t 
w25qxx_read_id(Device_t* pstDevice, uint16_t* pu16ID);

DEV_RET_t 
w25qxx_read_data(Device_t* pstDevice, uint8_t* pu8RxData, uint32_t u32Addr, uint32_t u32Len);

DEV_RET_t 
w25qxx_write_sector(Device_t* pstDevice, uint8_t* pu8TxData, uint32_t u32Addr);

DEV_RET_t 
w25qxx_write_data(Device_t* pstDevice, uint8_t* pu8TxData, uint32_t u32Addr, uint32_t u32Len);

DEV_RET_t 
w25qxx_clear_sector(Device_t* pstDevice, uint32_t u32Addr);

// DEV_RET_t 
// w25qxx_clear_block32(Device_t* pstDevice, uint32_t u32Addr);

// DEV_RET_t 
// w25qxx_clear_block64(Device_t* pstDevice, uint32_t u32Addr);

DEV_RET_t 
w25qxx_clear_chip(Device_t* pstDevice);

#ifdef __cplusplus
}
#endif

#endif // __W25QXX_H__
